package com.lzyyj.common;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 扩展Apache Commons BeanUtils, 提供一些反射方面缺失功能的封装.
 *
 * @author lzyyj
 */
public class BeanUtilsExt extends BeanUtils {

    protected static final Log log = LogFactory.getLog(BeanUtilsExt.class);

    private static final String UNDERLINE = "_";

    /**
     * 匹配getter方法的正则表达式
     */
    private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)");

    /**
     * 匹配setter方法的正则表达式
     */
    private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)");

    /**
     * 工具类，构造函数私有，避免被实例化
     */
    private BeanUtilsExt() {
    }

    /**
     * 循环向上转型,获取对象的DeclaredField.
     *
     * @throws NoSuchFieldException 如果没有该Field时抛出.
     */
    public static Field getDeclaredField(Object object, String propertyName) throws NoSuchFieldException {
        Field field = null;

        if (object != null && StringUtils.isNotEmpty(propertyName)) {
            field = getDeclaredField(object.getClass(), propertyName);
        }
        return field;
    }

    /**
     * 循环向上转型,获取对象的DeclaredField.
     *
     * @throws NoSuchFieldException 如果没有该Field时抛出.
     */
    public static Field getDeclaredField(Class<?> clazz, String propertyName) throws NoSuchFieldException {
        Field field;

        if (clazz == null || clazz == Object.class) {
            log.warn("没找指定有效的对象类型：(" + clazz + ")");
            throw new NoSuchFieldException("没找指定有效的对象类型：(" + clazz + ")");
        } else if (propertyName == null || propertyName.isEmpty()) {
            log.warn("没找指定有效的属性名：(" + propertyName + ")");
            throw new NoSuchFieldException("没找指定有效的属性名：(" + propertyName + ")");
        } else {
            for (Class<?> superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
                try {
                    field = superClass.getDeclaredField(propertyName);
                    return field;
                } catch (NoSuchFieldException e) {
                    // Field不在当前类定义,继续向上转型
                }
            }
            log.warn("没找到指定属性！(" + clazz.getSimpleName() + ": " + propertyName + ")");
            throw new NoSuchFieldException("No such field: " + clazz.getName() + '.' + propertyName);
        }
    }

    /**
     * 暴力获取对象变量值,忽略private,protected修饰符的限制.
     */
    public static Object forceGetProperty(Object object, String propertyName) {
        Object result = null;

        if (object == null || StringUtils.isEmpty(propertyName)) {
            return null;
        }

        Field field;
        try {
            field = getDeclaredField(object, propertyName);
            if (field != null) {
                result = field.get(object);
            }
        } catch (NoSuchFieldException | IllegalAccessException ignored) {
            log.warn("获取对象[" + object + "]的属性[" + propertyName + "]失败");
        }

        return result;
    }

    /**
     * 暴力设置对象变量值,忽略private,protected修饰符的限制.
     */
    public static void forceSetProperty(Object object, String propertyName, Object newValue) {
        if (object != null && StringUtils.isNotEmpty(propertyName)) {
            Field field = null;
            try {
                field = getDeclaredField(object, propertyName);
                if (field != null) {
                    Field finalField = field;
                    AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
                        try {
                            finalField.set(object, newValue);
                            return null;
                        } catch (IllegalAccessException e) {
                            log.warn("设置对象[" + object + "]的属性[" + propertyName + "]失败");
                            return null;
                        }
                    });
                }
            } catch (NoSuchFieldException e) {
                log.warn("找不到指定的字段");
            }
        }
    }

    /**
     * 暴力调用对象函数,忽略private,protected修饰符的限制.
     *
     * @throws NoSuchMethodException 如果没有该Method时抛出.
     */
    public static Object invokePrivateMethod(Object object, String methodName, Object... params) throws NoSuchMethodException {
        Object result = null;

        if (object != null && StringUtils.isNotEmpty(methodName)) {
            Class<?>[] types = new Class<?>[params.length];
            for (int i = 0; i < params.length; i++) {
                types[i] = params[i].getClass();
            }

            Class<?> clazz = object.getClass();
            Method method = null;
            for (Class<?> superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
                try {
                    method = superClass.getDeclaredMethod(methodName, types);
                    break;
                } catch (NoSuchMethodException e) {
                    // 方法不在当前类定义,继续向上转型
                }
            }

            if (method == null)
                throw new NoSuchMethodException("No Such Method:" + clazz.getSimpleName() + methodName);

            try {
                result = method.invoke(object, params);
            } catch (Exception e) {
                throw new NoSuchMethodException("invoke Exception:" + clazz.getSimpleName() + methodName);
            }
        }

        return result;
    }

    /**
     * 按Filed的类型取得Field列表.
     */
    public static List<Field> getFieldsByType(Object object, Class<?> type) {
        List<Field> list = new ArrayList<>();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.getType().isAssignableFrom(type)) {
                list.add(field);
            }
        }
        return list;
    }

    /**
     * 是否存在指定属性，支持小数点连接的外键关联对象
     *
     * @param example      源实例
     * @param propertyName 属性名
     * @return 结果
     */
    public static <T> boolean existsProperty(T example, String propertyName) {
        boolean exists = false;

        // 相应属性Getter方法获得的值类型
        Class<?> valueClass = null;

        valueClass = example.getClass();
        // 检查属性中的外键关联
        String[] names = propertyName.split("\\.");
        if (names.length > 1) {
            // 有外键需要关联
            StringBuilder associationPath = null;

            Object entity = example;

            // 逐级解析值类型
            for (int i = 0; i < names.length - 1; i++) {
                if (associationPath == null) {
                    associationPath = new StringBuilder(names[i]);
                } else {
                    associationPath.append(".").append(names[i]);
                }

                if (entity != null) {
                    // 迭代为下一级关联对象
                    try {
                        valueClass = getPropertyType(valueClass, names[i]);
                        entity = PropertyUtils.getProperty(entity, names[i]);
                    } catch (Exception e) {
                    }

                    if (valueClass.isAssignableFrom(Collection.class) && entity != null && ((Collection<?>) entity).size() == 1) {
                        // 如果是一个非空集合类型，才需要关联，并且只取一个条目
                        for (Object item : (Collection<?>) entity) {
                            entity = item;
                            valueClass = entity.getClass();
                            break;
                        }
                    }
                }
            }

            if (entity != null) {
                try {
                    getProperty(entity, names[names.length - 1]);
                    exists = true;
                } catch (Exception ignored) {
                }
            }
        } else {
            // 不需要关联外键，直接获取类型及值
            if (example instanceof Map) {
                exists = ((Map<?, ?>) example).containsKey(propertyName);
            } else {
                try {
                    getProperty(example, propertyName);
                    exists = true;
                } catch (Exception ignored) {
                }
            }
        }

        return exists;
    }

    /**
     * 按FiledName获得Field的类型.
     */
    public static Class<?> getPropertyType(Class<?> clazz, String name) {
        // 1. 尝试通过 getter 方法获取属性类型
        String getterName = "get" + capitalize(name);
        try {
            Method getter = clazz.getMethod(getterName);
            return getter.getReturnType();
        } catch (NoSuchMethodException ignored) {
            // getter 方法不存在，继续尝试 is 方法（针对布尔类型）
        }

        // 2. 尝试通过 is 方法获取属性类型（针对布尔类型）
        String isName = "is" + capitalize(name);
        try {
            Method isMethod = clazz.getMethod(isName);
            return isMethod.getReturnType();
        } catch (NoSuchMethodException ignored) {
            // is 方法不存在，继续尝试 setter 方法
        }

        // 3. 尝试通过 setter 方法获取属性类型
        String setterName = "set" + capitalize(name);
        for (Method method : clazz.getMethods()) {
            if (method.getName().equals(setterName) && method.getParameterCount() == 1) {
                return method.getParameterTypes()[0];
            }
        }

        // 4. 如果未找到 getter 或 setter 方法，返回 null
        return null;
    }

    /**
     * 将字符串首字母大写。
     *
     * @param str 输入字符串
     * @return 首字母大写的字符串
     */
    private static String capitalize(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toUpperCase(Locale.ROOT) + str.substring(1);
    }

    /**
     * 解析属性值，并分析需要添加的外键关联
     *
     * @param example      实体对象
     * @param propertyName 属性名
     * @return 返回结果
     */
    public static <T> Object getPropertyValueObj(T example, String propertyName) {
        Object result = null;
        try {
            result = getPropertyValue(example, propertyName);
        } catch (Exception ignored) {
        }
        return result;
    }

    /**
     * 解析属性值，并分析需要添加的外键关联
     *
     * @param example      实体对象
     * @param propertyName 属性名
     * @return 返回结果
     * @throws Exception 可能发生的异常
     */
    public static <T> Object getPropertyValue(T example, String propertyName) throws Exception {
        Object value = null;

        // 相应属性Setter方法应有的参数类型
        Class<?> paraClass = null;
        // 相应属性Getter方法获得的值类型
        Class<?> valueClass = null;

        // 检查属性中的外键关联
        String[] names = propertyName.split("\\.");
        if (names.length > 1) {
            // 有外键需要关联
            StringBuilder associationPath = null;
            String aliasName = null;

            valueClass = example.getClass();
            Object entity = example;

            // 逐级解析值类型
            for (int i = 0; i < names.length - 1; i++) {
                if (associationPath == null) {
                    associationPath = new StringBuilder(names[i]);
                } else {
                    associationPath.append(".").append(names[i]);
                }
                aliasName = names[i];

                if (entity != null) {
                    // 迭代为下一级关联对象
                    valueClass = getPropertyType(valueClass, names[i]);
                    entity = PropertyUtils.getProperty(entity, names[i]);

                    if (valueClass.isAssignableFrom(Collection.class) && entity != null && ((Collection<?>) entity).size() == 1) {
                        // 如果是一个非空集合类型，才需要关联，并且只取一个条目
                        for (Object item : (Collection<?>) entity) {
                            entity = item;
                            valueClass = entity.getClass();
                            break;
                        }
                    }
                }
            }

            if (entity != null) {
                try {
                    value = PropertyUtils.getProperty(entity, names[names.length - 1]);
                } catch (Exception ignored) {
                }
            }
        } else {
            // 不需要关联外键，直接获取类型及值
            try {
                value = PropertyUtils.getProperty(example, propertyName);
            } catch (Exception ignored) {
            }
        }

        return value;
    }

    /**
     * 解析属性值，并分析需要添加的外键关联
     *
     * @param target       目标实体
     * @param propertyName 属性名
     * @param value        属性值
     */
    public static <T> void setPropertyValueObj(T target, String propertyName, Object value) {
        try {
            setPropertyValue(target, propertyName, value);
        } catch (Exception ignored) {
        }
    }

    /**
     * 尝试将值转换为指定的类型。
     *
     * @param value      要转换的值
     * @param targetType 目标类型
     * @return 转换后的值，如果无法转换则返回null
     */
    private static Object convertValue(Object value, Class<?> targetType) {
        if (value == null) {
            return null;
        }

        if (targetType.isInstance(value)) {
            // 值已经是目标类型或其子类，无需转换
            return value;
        }

        // 尝试进行类型转换
        if (Number.class.isAssignableFrom(targetType)) {
            // 处理数字类型的转换
            if (value instanceof String) {
                try {
                    if (targetType == Integer.class || targetType == int.class) {
                        return Integer.parseInt((String) value);
                    } else if (targetType == Long.class || targetType == long.class) {
                        return Long.parseLong((String) value);
                    } else if (targetType == Double.class || targetType == double.class) {
                        return Double.parseDouble((String) value);
                    } else if (targetType == Float.class || targetType == float.class) {
                        return Float.parseFloat((String) value);
                    }
                } catch (NumberFormatException e) {
                    // 转换失败，返回null
                    return null;
                }
            }
        } else if (targetType == String.class) {
            // 转换为字符串类型
            return value.toString();
        } else if (targetType == Boolean.class || targetType == boolean.class) {
            // 转换为布尔类型
            if (value instanceof String) {
                String strValue = (String) value;
                return Boolean.parseBoolean(strValue);
            } else if (value instanceof Number) {
                return ((Number) value).longValue() != 0;
            }
        }

        // 无法转换的类型，返回null
        return null;
    }

    /**
     * 解析属性值，并分析需要添加的外键关联
     *
     * @param target       目标实体
     * @param propertyName 属性名
     * @param value        属性值
     * @throws Exception 可能发生的异常
     */
    public static <T> void setPropertyValue(T target, String propertyName, Object value) throws Exception {

        if (target != null && propertyName != null && !propertyName.isEmpty()) {
            // 相应属性Setter方法应有的参数类型
            Class<?> paraClass = null;
            // 相应属性Getter方法获得的值类型
            Class<?> valueClass = target.getClass();

            // 检查属性中的外键关联
            String[] names = propertyName.split("\\.");
            if (names.length > 1) {
                // 有外键需要关联
                String aliasName = null;

                Object entity = target;

                // 逐级解析值类型
                for (int i = 0; i < names.length - 1; i++) {
                    if (aliasName == null) {
                        aliasName = names[i];
                    } else {
                        aliasName += "." + names[i];
                    }

                    if (entity != null) {
                        // 迭代为下一级关联对象
                        valueClass = getPropertyType(valueClass, names[i]);
                        entity = PropertyUtils.getProperty(entity, names[i]);

                        if (valueClass.isAssignableFrom(Collection.class)) {
                            // 集合，暂不考虑
                            if (entity != null && ((Collection<?>) entity).size() == 1) {

                            }
                        } else {
                            if (entity == null && !valueClass.isInterface()) {
                                entity = valueClass.newInstance();
                            }
                        }
                    }
                }

                if (entity != null && existsProperty(entity, names[names.length - 1])) {
                    BeanUtils.setProperty(entity, names[names.length - 1], value);
//                    setPropertyValue1(target, names[names.length - 1], value);
                }
            } else {
                valueClass = getPropertyType(valueClass, propertyName);
                // 不需要关联外键，直接获取类型及值
                if (existsProperty(target, propertyName)) {
                    if (valueClass == Date.class) {
                        log.debug("调试：");
                    }
                    try {
                        BeanUtils.setProperty(target, propertyName, value);
                    } catch (Exception ignored) {
                    }
                }
//                setPropertyValue1(target, propertyName, value);
            }
        }

    }

    /**
     * 解析属性值，并设置到目标实体的指定属性中。
     * 如果属性值与目标实体的属性类型不兼容，尝试进行常见的类型转换。
     *
     * @param target       目标实体
     * @param propertyName 属性名
     * @param value        属性值
     * @throws NoSuchFieldException   如果目标实体没有指定名称的属性
     * @throws IllegalAccessException 如果无法访问或修改该属性
     */
    private static <T> void setPropertyValue1(T target, String propertyName, Object value) throws NoSuchFieldException, IllegalAccessException {
        Field field = target.getClass().getDeclaredField(propertyName);
        field.setAccessible(true);

        Class<?> fieldType = field.getType();
        Object convertedValue = convertValue(value, fieldType);

        if (convertedValue == null && value != null) {
            throw new IllegalArgumentException("无法将提供的值: value=" + value + ", 转换为字段类型: " + fieldType.getName() + "(" + propertyName + ")");
        }

        field.set(target, convertedValue);
    }

    /**
     * Bean属性复制工具方法。
     *
     * @param dest 目标对象
     * @param src  源对象
     */
    public static void copyBeanProp(Object dest, Object src) {
        try {
            copyProperties(src, dest);
        } catch (Exception ignored) {
        }
    }

    /**
     * 获取对象的getter方法。
     *
     * @param obj 对象
     * @return 对象的getter方法列表
     */

    public static List<Method> getGetterMethods(Object obj) {
        // getter方法列表
        List<Method> getterMethods = new ArrayList<>();
        // 获取所有方法
        Method[] methods = obj.getClass().getMethods();
        // 查找getter方法
        for (Method method : methods) {
            Matcher m = GET_PATTERN.matcher(method.getName());
            if (m.matches() && (method.getParameterTypes().length == 0)) {
                getterMethods.add(method);
            }
        }
        // 返回getter方法列表
        return getterMethods;
    }

    /**
     * 获取对象的setter方法。
     *
     * @param obj 对象
     * @return 对象的setter方法列表
     */
    public static List<Method> getSetterMethods(Object obj) {
        // setter方法列表
        List<Method> setterMethods = new ArrayList<>();

        // 获取所有方法
        Method[] methods = obj.getClass().getMethods();

        // 查找setter方法

        for (Method method : methods) {
            Matcher m = SET_PATTERN.matcher(method.getName());
            if (m.matches() && (method.getParameterTypes().length == 1)) {
                setterMethods.add(method);
            }
        }
        // 返回setter方法列表
        return setterMethods;
    }

    /**
     * 获得field的getter函数,如果找不到该方法,返回null.
     *
     * @param type      实体类型
     * @param fieldName 字段名
     * @return 结果
     */
    public static String getGetterName(Class<?> type, String fieldName) {
        String getterName = null;

        if (type != null && fieldName != null && !fieldName.isEmpty()) {
            if (type.getName().equals("boolean")) {
                getterName = "is" + StringUtils.capitalize(fieldName);
            } else {
                getterName = "get" + StringUtils.capitalize(fieldName);
            }
        }

        return getterName;
    }

    /**
     * 获得field的getter函数,如果找不到该方法,返回null.
     */
    public static Method getGetterMethod(Class<?> type, String fieldName) {
        Method method = null;

        if (type != null && fieldName != null && fieldName.length() > 0) {
            try {
                method = type.getMethod(getGetterName(type, fieldName));
            } catch (NoSuchMethodException e) {
            }
        }

        return method;
    }

    /**
     * @param objClass   对象类型
     * @param methodName 方法名
     * @param paras      参数列表
     * @return 结果
     */
    public static Method getMethod(Class<?> objClass, String methodName, Class<?>... paras) {
        Method method;
        if (paras.length == 0) {
            try {
                method = objClass.getMethod(methodName);
            } catch (NoSuchMethodException e) {
                method = null;
            }
        } else {
            try {
                method = objClass.getMethod(methodName, paras);
            } catch (NoSuchMethodException e) {
                method = null;
            }
            Class<?> clazz = paras[0].getSuperclass();
            while (method == null && clazz != null) {
                if (clazz != null) {
                    paras[0] = clazz;
                    try {
                        method = objClass.getMethod(methodName, paras);
                    } catch (NoSuchMethodException ignored) {
                    }
                }
                clazz = clazz.getSuperclass();
            }
        }

        return method;
    }

    /**
     * 获取同时具有 getter 和 setter 方法的属性列表
     *
     * @param clazz 对象类型
     * @return 属性列表（逗号分隔）
     */
    public static String getPropertyList(Class<?> clazz) {
        List<String> properties = new ArrayList<>();
        getPropertyNamesRecursive(clazz, properties);
        // 将属性列表拼接为逗号分隔的字符串
        return String.join(",", properties);
    }

    private static void getPropertyDescriptorsRecursive(Class<?> clazz, List<String> properties) {
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
            PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor descriptor : descriptors) {
                if (descriptor.getReadMethod() != null && descriptor.getWriteMethod() != null) {
                    properties.add(descriptor.getName());
                }
            }
            // 递归处理父类
            if (clazz.getSuperclass() != null) {
                getPropertyDescriptorsRecursive(clazz.getSuperclass(), properties);
            }
        } catch (Exception e) {
            // 处理可能的异常，例如 IntrospectionException
            e.printStackTrace();
            // 可以选择抛出或记录日志，或者忽略异常（这里选择打印堆栈跟踪作为示例）
        }
    }

    private static void getPropertyNamesRecursive(Class<?> clazz, List<String> properties) {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            String fieldName = field.getName();
            String capitalizedFieldName = capitalize(fieldName);

            try {
                Method getter = clazz.getMethod("get" + capitalizedFieldName);
                Method setter = clazz.getMethod("set" + capitalizedFieldName, field.getType());

                if (getter != null && setter != null) {
                    properties.add(fieldName);
                }
            } catch (NoSuchMethodException e) {
                // 忽略没有 getter 或 setter 方法的字段
            }
        }

        // 递归处理父类
        Class<?> superclass = clazz.getSuperclass();
        if (superclass != null && !superclass.equals(Object.class)) {
            getPropertyNamesRecursive(superclass, properties);
        }
    }

    /**
     * 获取类的所有属性描述符
     *
     * @param clazz 对象类型
     * @return 属性描述符数组
     */
    private static PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz) {
        try {
            // 使用 Introspector 获取属性描述符
            return Introspector.getBeanInfo(clazz).getPropertyDescriptors();
        } catch (Exception e) {
            throw new RuntimeException("Failed to get property descriptors for class: " + clazz.getName(), e);
        }
    }

    /**
     * 获取属性键值对
     *
     * @param clazz 对象类型
     * @return 属性键值对
     */
    public static Map<String, Object> getPropertyMap(Class<?> clazz) {
        Map<String, Object> propertyMap = new HashMap<>();

        if (clazz != null) {
            for (PropertyDescriptor property : getPropertyDescriptors(clazz)) {
                propertyMap.put(property.getName(), property.getPropertyType());
            }
        }

        return propertyMap;
    }

    /**
     * 属性复制
     *
     * @param source       源对象
     * @param target       目标对象
     * @param propertyList 需要处理的属性列表
     * @throws Exception 可能的异常
     */
    public static void copyProperties(Object source, Object target, String propertyList) throws Exception {

        Set<String> propertySet = new HashSet<>();
        if (StringUtils.isNotEmpty(propertyList)) {
            String[] properties = propertyList.split(",");
            propertySet.addAll(Arrays.asList(properties));
        }
        if (propertySet.isEmpty()) {
            Set<String> sourcePropertySet = new HashSet<>(Arrays.asList(getPropertyList(source.getClass()).split(",")));
            Set<String> targetPropertySet = new HashSet<>(Arrays.asList(getPropertyList(target.getClass()).split(",")));
            for (String property : sourcePropertySet) {
                if (targetPropertySet.contains(property)) {
                    propertySet.add(property);
                    targetPropertySet.remove(property);
                }
            }
            sourcePropertySet.removeAll(propertySet);
            for (String property : sourcePropertySet) {
                String targetProperty = null;
                for (String property1 : targetPropertySet) {
                    if (property1.startsWith(property) || property.startsWith(property1)) {
                        targetProperty = property1;
                        break;
                    }else if(property1.equalsIgnoreCase(property)){
                        targetProperty = property1;
                        break;
                    }
                }
                if (StringUtils.isNotBlank(targetProperty)) {
                    targetPropertySet.remove(property);
                    propertySet.add(property+":"+targetProperty);
                }
            }
            log.debug("调试：sourcePropertySet=" + sourcePropertySet + ",targetPropertySet=" + targetPropertySet);
        }
        for (String propertyString : propertySet) {
            if (propertyString.length() > 1) {
                String sourceProperty;
                String targetProperty;
                String[] propertyPairs = propertyString.split(":");
                switch (propertyPairs.length) {
                    case 1:
                        sourceProperty = propertyPairs[0];
                        targetProperty = propertyPairs[0];
                        break;
                    case 2:
                        sourceProperty = propertyPairs[0];
                        targetProperty = propertyPairs[1];
                        break;
                    default:
                        sourceProperty = null;
                        targetProperty = null;
                        break;
                }
                if (sourceProperty != null) {
                    Object value = getPropertyValue(source, sourceProperty);
                    if (value instanceof Collection) {
                        Collection<Object> sourceCollection = (Collection<Object>) value;
                        log.debug("集合属性！");
                        Object oldValue = getPropertyValue(target, targetProperty);
                        if (oldValue != null) {
                            if (oldValue instanceof Collection) {
                                Collection<Object> targetCollection = (Collection<Object>) oldValue;
                                targetCollection.clear();
                                log.debug("清空目标集合属性！");
                                for (Object o : sourceCollection) {
                                    targetCollection.add(o);
                                }
                            }
                        } else {
                            // 目标原属性为空
                        }
                    } else {
                        try {
                            setPropertyValue(target, targetProperty, value);
                        } catch (Exception ignored) {
                            log.debug("调试：");
                        }
                    }
                }
            }
        }
    }

    public static Class<?> getMemberType(Class<?> clazz, String name) {
        Class<?> result = null;

        Field field;
        try {
            field = getDeclaredField(clazz, name);
        } catch (NoSuchFieldException e) {
            field = null;
        }
        if (field != null) {
            Type genType = field.getGenericType();
            if (genType instanceof ParameterizedType) {
                Type rawType = ((ParameterizedType) genType).getRawType();
                Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

                if (params.length > 0) {
                    // 处理具体类型
                    if (params[0] instanceof Class) {
                        result = (Class<?>) params[0];
                    }
                    // 处理泛型变量（需通过上下文获取实际类型）
                    else if (params[0] instanceof TypeVariable) {
                        TypeVariable<?> typeVar = (TypeVariable<?>) params[0];
                        result = resolveTypeVariable(clazz, typeVar);
                    }
                }
            }

        }

        return result;
    }

    private static Class<?> resolveTypeVariable(Class<?> clazz, TypeVariable<?> typeVar) {
        // 获取类的泛型声明
        Type superClass = clazz.getGenericSuperclass();
        if (superClass instanceof ParameterizedType) {
            ParameterizedType pt = (ParameterizedType) superClass;

            // 查找父类中对应泛型参数的实际类型
            Type[] actualTypes = pt.getActualTypeArguments();
            TypeVariable<?>[] declaredTypes = ((Class<?>) pt.getRawType()).getTypeParameters();

            for (int i = 0; i < declaredTypes.length; i++) {
                if (declaredTypes[i].getName().equals(typeVar.getName())) {
                    if (actualTypes[i] instanceof Class) {
                        return (Class<?>) actualTypes[i];
                    }
                }
            }
        }
        return null; // 无法解析时返回null
    }

    public static boolean isProperty(Class<?> clazz, String property) {
        return getGetterMethod(clazz, property) != null;
    }

    /***
     * 下划线命名转为驼峰命名
     *
     * @param para
     *        下划线命名的字符串
     */

    public static String underlineToHump(String para) {
        StringBuilder result = new StringBuilder();

        String[] a = para.toLowerCase().split(UNDERLINE);
        for (String s : a) {
            if (!para.contains(UNDERLINE)) {
                result.append(s);
                continue;
            }
            if (result.length() == 0) {
                result.append(s.toLowerCase());
            } else {
                result.append(s.substring(0, 1).toUpperCase());
                result.append(s.substring(1).toLowerCase());
            }
        }

        return result.toString();
    }

    /***
     * 驼峰命名转为下划线命名
     *
     * @param para
     *        驼峰命名的字符串
     */

    public static String humpToUnderline(String para) {
        StringBuilder sb = new StringBuilder(para);

        int temp = 0;//定位
        if (!para.contains(UNDERLINE)) {
            for (int i = 0; i < para.length(); i++) {
                if (Character.isUpperCase(para.charAt(i))) {
                    sb.insert(i + temp, UNDERLINE);
                    temp += 1;
                }
            }
        }
        return sb.toString().toUpperCase();
    }

    public static boolean hasProperty(Class<?> clazz, String propertyName) {
        // 检查字段
        if (hasField(clazz, propertyName)) {
            return true;
        }
        // 检查 getter 方法
        if (hasGetter(clazz, propertyName)) {
            return true;
        }
        // 检查 setter 方法
        return hasSetter(clazz, propertyName);
    }

    private static boolean hasField(Class<?> clazz, String propertyName) {
        try {
            clazz.getDeclaredField(propertyName);
            return true;
        } catch (NoSuchFieldException e) {
            return false;
        }
    }

    private static boolean hasGetter(Class<?> clazz, String propertyName) {
        String getterName = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
        try {
            Method method = clazz.getMethod(getterName);
            if (method.getParameterCount() == 0) {
                return true;
            }
        } catch (NoSuchMethodException e) {
            // 如果不是标准的 getter，可能是 boolean 类型的 isXXX
            if (propertyName.startsWith("is") && propertyName.length() > 2) {
                String isGetterName = propertyName;
                try {
                    Method method = clazz.getMethod(isGetterName);
                    if (method.getParameterCount() == 0 && method.getReturnType() == boolean.class) {
                        return true;
                    }
                } catch (NoSuchMethodException ex) {
                    // 忽略异常
                }
            }
        }
        return false;
    }

    private static boolean hasSetter(Class<?> clazz, String propertyName) {
        String setterName = "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
        try {
            Method method = clazz.getMethod(setterName, new Class[]{String.class}); // 假设属性类型为 String，可以根据需要修改
            if (method.getParameterCount() == 1) {
                return true;
            }
        } catch (NoSuchMethodException e) {
            // 忽略异常
        }
        return false;
    }

}
